import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
import { Button, Input } from 'antd';
import React, { useMemo, useState } from 'react';
import { NodeProps, Position } from 'reactflow';
import { useContextSelector } from 'use-context-selector';

import CollapsibleSection from '@/components/CollapsibleSection';
import { t } from '@/locales/i18n';
import { getNanoid } from '@/pages/chat/tools/tools';
import { NodeInputKeyEnum } from '@/types/workflow/constant';
import { FlowNodeInputItemType } from '@/types/workflow/io';
import { FlowNodeItemType } from '@/types/workflow/node';
import { ClassifyQuestionAgentItemType } from '@/types/workflow/template/system/classifyQuestion/type';
import { getHandleId } from '@/types/workflow/utils';

import { WorkflowContext } from '../../../context';
import { SourceHandle } from '../render/Handle';
import NodeCard from '../render/NodeCard';
import RenderInput from '../render/RenderInput';

const { TextArea } = Input;

const NodeCQNode = ({ data, selected }: NodeProps<FlowNodeItemType>) => {
  const { nodeId, inputs } = data;
  const onChangeNode = useContextSelector(WorkflowContext, (v) => v.onChangeNode);

  const [expandedSections, setExpandedSections] = useState<Set<'output' | 'input' | 'params'>>(
    new Set(['input']),
  );

  const toggleSection = (section: 'output' | 'input' | 'params') => {
    setExpandedSections((prev) => {
      const newSet = new Set(prev);
      if (newSet.has(section)) {
        newSet.delete(section);
      } else {
        newSet.add(section);
      }
      return newSet;
    });
  };

  const filterHiddenInputs = inputs.filter((item) => true);
  const requiredInputs = filterHiddenInputs.filter((item) => item.required);
  const optionalInputs = filterHiddenInputs.filter(
    (item) => !item.required && item.key !== 'agents',
  );
  const angentsInputs = filterHiddenInputs.filter(
    (item) => !item.required && item.key === 'agents',
  );

  const requireText = useMemo(() => {
    return requiredInputs
      .filter((item) => item.label !== '')
      .map((item) => t(item.label as any))
      .join('，');
  }, [requiredInputs]);

  const CustomComponent = useMemo(
    () => ({
      [NodeInputKeyEnum.agents]: ({
        key: agentKey,
        value = [],
        ...props
      }: FlowNodeInputItemType) => {
        const agents = value as ClassifyQuestionAgentItemType[];
        return (
          <div className="-mt-5 flex flex-col gap-1">
            {agents.map((item, i) => (
              <div key={item.key}>
                <div className="flex w-full items-center">
                  <div className="ml-1 flex-1 text-xs font-font-weight-600 text-text-4">
                    {t('classification') + (i + 1)}
                  </div>

                  <Button
                    type="text"
                    icon={<MinusCircleOutlined className="group-hover:text-error" />}
                    className="group mt-1 cursor-pointer text-text-4 hover:text-error"
                    style={{
                      color: 'var(--text-4)',
                    }}
                    onClick={() => {
                      onChangeNode({
                        nodeId,
                        type: 'updateInput',
                        key: agentKey,
                        value: {
                          ...props,
                          key: agentKey,
                          value: agents.filter((input) => input.key !== item.key),
                        },
                      });
                      onChangeNode({
                        nodeId,
                        type: 'delOutput',
                        key: item.key,
                      });
                    }}
                  />
                </div>
                <div className="relative w-full">
                  <TextArea
                    rows={2}
                    className="nodrag mt-1 bg-white text-sm text-text-4"
                    style={{
                      color: 'var(--text-4)',
                    }}
                    defaultValue={item.value}
                    onChange={(e) => {
                      const newVal = agents.map((val) =>
                        val.key === item.key
                          ? {
                              ...val,
                              value: e.target.value,
                            }
                          : val,
                      );
                      onChangeNode({
                        nodeId,
                        type: 'updateInput',
                        key: agentKey,
                        value: {
                          ...props,
                          key: agentKey,
                          value: newVal,
                        },
                      });
                    }}
                  />
                  <SourceHandle
                    nodeId={nodeId}
                    handleId={getHandleId(nodeId, 'source', item.key)}
                    position={Position.Right}
                    translate={[30, 0]}
                  />
                </div>
              </div>
            ))}
            <div className="mt-2 flex items-center justify-center">
              <Button
                className="text-sm"
                type="text"
                icon={<PlusOutlined />}
                onClick={() => {
                  const key = getNanoid();
                  onChangeNode({
                    nodeId,
                    type: 'updateInput',
                    key: agentKey,
                    value: {
                      ...props,
                      key: agentKey,
                      value: agents.concat({ value: '', key }),
                    },
                  });
                }}
              >
                {t('core.module.Add question type')}
              </Button>
            </div>
          </div>
        );
      },
    }),
    [nodeId, onChangeNode],
  );

  const RenderHandle = useMemo(
    () => ({
      [NodeInputKeyEnum.agents]: ({
        key: agentKey,
        value = [],
        ...props
      }: FlowNodeInputItemType) => {
        const agents = value as ClassifyQuestionAgentItemType[];
        return (
          <div>
            {agents.map((item, i) => (
              <div key={item.key} className="relative w-full">
                <SourceHandle
                  nodeId={nodeId}
                  handleId={getHandleId(nodeId, 'source', item.key)}
                  position={Position.Right}
                  translate={[26, 0]}
                />
              </div>
            ))}
          </div>
        );
      },
    }),
    [nodeId],
  );

  const Render = useMemo(() => {
    return (
      <NodeCard minW="400px" selected={selected} {...data}>
        <div className="flex flex-col gap-3">
          <CollapsibleSection
            title={t('workflow.node.basic_config')}
            subtitle={`${t('workflow.node.basic_config_desc')}(${requireText})`}
            isExpanded={expandedSections.has('input')}
            onToggle={() => toggleSection('input')}
            type="input"
          >
            <RenderInput
              nodeId={nodeId}
              flowInputList={requiredInputs}
              CustomComponent={CustomComponent}
            />
          </CollapsibleSection>
          <CollapsibleSection
            title={t('workflow.node.variable_config')}
            subtitle={t('workflow.node.variable_config_desc')}
            isExpanded={expandedSections.has('params')}
            onToggle={() => toggleSection('params')}
            type="params"
          >
            <RenderInput nodeId={nodeId} flowInputList={optionalInputs} />
          </CollapsibleSection>
          <CollapsibleSection
            title="分类配置"
            subtitle="定义分类类别"
            isExpanded={expandedSections.has('output')}
            onToggle={() => toggleSection('output')}
            type="output"
            tag={`${angentsInputs.length > 0 ? angentsInputs[0].value.length : ''}个分类`}
            className="pb-3"
          >
            {expandedSections.has('output') && (
              <RenderInput
                nodeId={nodeId}
                flowInputList={angentsInputs}
                CustomComponent={CustomComponent}
              />
            )}
          </CollapsibleSection>
        </div>

        {!expandedSections.has('output') && (
          <div className="absolute bottom-12 right-6">
            {RenderHandle.agents({ ...angentsInputs[0] })}
          </div>
        )}
      </NodeCard>
    );
  }, [
    selected,
    data,
    requireText,
    expandedSections,
    nodeId,
    requiredInputs,
    CustomComponent,
    optionalInputs,
    angentsInputs,
    RenderHandle,
  ]);

  return Render;
};
export default React.memo(NodeCQNode);
